package com.blockmeta.bbs.immodule.corebean.Impl;

import android.content.Context;
import android.text.TextUtils;

import com.blankj.utilcode.util.LogUtils;
import com.blockmeta.bbs.baselibrary.net.callback.Callback;
import com.blockmeta.bbs.baselibrary.utils.FormatUtil;
import com.blockmeta.bbs.baselibrary.utils.UUIDUtil;
import com.blockmeta.bbs.baselibrary.utils.gson.GsonUtil;
import com.blockmeta.bbs.businesslibrary.constant.NetConstant;
import com.blockmeta.bbs.businesslibrary.eventbus.IMMsgCountEvent;
import com.blockmeta.bbs.businesslibrary.flutter.MethodChannelFlutterPlugins;
import com.blockmeta.bbs.businesslibrary.net.okhttp.OKHttpGetReq;
import com.blockmeta.bbs.businesslibrary.pojo.CoinsDetailPOJO;
import com.blockmeta.bbs.businesslibrary.pojo.MessageParam;
import com.blockmeta.bbs.businesslibrary.util.AccountHelper;
import com.blockmeta.bbs.immodule.adapter.ImSessionListAdapter;
import com.blockmeta.bbs.immodule.bean.Params;
import com.blockmeta.bbs.immodule.bean.databean.KlineContentBean;
import com.blockmeta.bbs.immodule.corebean.IChatMessageDomainService;
import com.blockmeta.bbs.immodule.corebean.IDomainCommonManger;
import com.blockmeta.bbs.immodule.dao.ChatMessage;
import com.blockmeta.bbs.immodule.dao.IMUserEntity;
import com.blockmeta.bbs.immodule.greendao.repository.IChatMessageRepo;

import org.greenrobot.eventbus.EventBus;

import java.util.HashMap;
import java.util.List;


/**
 * domain 层不能相互调用，只能调用自己的repo,避免耦合,可以调用manager,用于通用业务逻辑封装
 */
public class ChatMessageDomainService implements IChatMessageDomainService {
    final Context mContext;
    IChatMessageRepo chatMessageRepo;
    IDomainCommonManger domainCommonManger;


    public ChatMessageDomainService(Context context) {
        mContext = context;
        chatMessageRepo = IMRepoContext.getChatMessageRepo(context);
        domainCommonManger = IMApplicationContext.getDomainCommonManger();
    }


    @Override
    public ChatMessage makeChatMessage(MessageParam messageParam) {
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setContent(messageParam.getContent());
        chatMessage.setType(ChatMessage.TYPE_SEND);
        int msgType = messageParam.getMsgType();
        chatMessage.setMsgType(msgType);
        chatMessage.setChatMessageId(messageParam.getMsgId());

        if (msgType == ChatMessage.MSG_TYPE_UU) {
            chatMessage.setToId(messageParam.getToId());
        } else if (msgType == ChatMessage.MSG_TYPE_UCG) {
            chatMessage.setChatGroupId(messageParam.getToId());
        }
        chatMessage.setFromId(AccountHelper.getUidInt());
        chatMessage.setWhoId(AccountHelper.getUidInt());
        //发送中。。。
        chatMessage.setStatus(ChatMessage.STATUS_SENDING);
        chatMessage.setDate((int) (System.currentTimeMillis() / 1000L));
        chatMessage.setChecked(true);
        chatMessage.setFileParam(messageParam.getFileParam());
        String uuid = UUIDUtil.uuid();
        chatMessage.setUuid(uuid);
        int contentType = messageParam.getContentType();
        chatMessage.setContentType(contentType);
        //文件！
        if (contentType != ChatMessage.CONTENT_TYPE_ATTACHMENT) {
            chatMessage.setFilePath("");
            chatMessage.setFileName("");
        } else {
            chatMessage.setFilePath(messageParam.getFileUrl());
            chatMessage.setFileName(messageParam.getFileName());
        }
        //用于自定义内容和文件的内部分类
        chatMessage.setFileType(messageParam.getFileType());


        return chatMessage;
    }



    @Override
    public void updateChatMessageReaded(Long id, boolean readorUnread) {
        chatMessageRepo.updateChatMessageReaded(id, readorUnread);
        sendUncheckCountEvent();
    }


    @Override
    public void deleteListChatMessage(long uidInt, ChatMessage cm) {
        long toId;
        if (cm.getMsgType() == ChatMessage.MSG_TYPE_UU) {
            if (cm.getType() == ChatMessage.TYPE_SEND) {
                toId = cm.getToId();
            } else {
                toId = cm.getFromId();
            }
        } else {
            toId = cm.getChatGroupId();
        }
        chatMessageRepo.deleteListChatMessage(AccountHelper.getUidInt()
                , toId, cm.getMsgType());
        sendUncheckCountEvent();
    }


    @Override
    public void updateChatMessageChecked(long uidInt, long toUserId, int msgTypeUcg) {
        if (msgTypeUcg == ChatMessage.MSG_TYPE_UU) {
            chatMessageRepo.updateChatMessageChecked(uidInt, toUserId);
        } else if (msgTypeUcg == ChatMessage.MSG_TYPE_UCG) {
            chatMessageRepo.updateGroupMessageCheck(uidInt, toUserId);
        }


        sendUncheckCountEvent();
    }




    private static final String[] CUSTOM_TYPE_ARRAY = {"", "F10","行情","名片","帖子","文章", "活动", "好物"};


    /**
     * 获取在聊天列表和通知中显示的内容，如果是群聊，需要传入用户信息
     * @param iMUserEntity
     * @param message
     * @return
     */
    @Override
    public String getShowContent(IMUserEntity iMUserEntity, ChatMessage message) {
        String content = message.getContent();
        int fileType = message.getFileType();
        if (message.getContentType() == ChatMessage.CONTENT_TYPE_ATTACHMENT) {
            if (fileType <= ChatMessage.TYPE_GIF) {
                content = "[图片]";
            } else {
                content = "[附件]";
            }
        }else if(message.getContentType() == ChatMessage.CONTENT_TYPE_CUSTOM){
            content = String.format("分享了[%s]", CUSTOM_TYPE_ARRAY[fileType]);
        }else if(message.getContentType() == ChatMessage.CONTENT_TYPE_HONGBAO){
            content = "收到一个红包";
        }
        if(message.getMsgType() == ChatMessage.MSG_TYPE_UCG ){
            if(message.getContentType() != ChatMessage.CONTENT_TYPE_HONGBAO){
                if(iMUserEntity != null){
                    String showName = domainCommonManger.getCircleRemarkName(iMUserEntity.getUserId()
                            , message.getChatGroupId(), iMUserEntity.getName(), iMUserEntity.getRemarkName());
                    content = showName + ": " + content;
                }else if(!TextUtils.isEmpty(message.getUserName())){
                    content = message.getUserName() + ": " + content;
                }
            }
            if(message.getContentType() == ChatMessage.CONTENT_TYPE_NOTIFY || message.getContentType() == ChatMessage.CONTENT_TYPE_NONOTIFY){
                //群聊中替换通知内容中的特殊格式
                long chatGroupId = message.getMsgType() == ChatMessage.MSG_TYPE_UCG ? message.getChatGroupId() : 0;
                content = domainCommonManger.getTagConvert(content, chatGroupId);
            }
        }
        return content;
    }


    /**
     * 发送到首页角标
     */
    @Override
    public void sendUncheckCountEvent() {
        int unCheckedCount = domainCommonManger.getUnCheckedMsgCount(AccountHelper.getUidInt());
        int unCheckedUUCount = domainCommonManger.getUnCheckedUUMsgCount(AccountHelper.getUidInt());
        int unCheckedUCGCount = domainCommonManger.getUnCheckedUCGMsgCount(AccountHelper.getUidInt());
        EventBus.getDefault().post(IMMsgCountEvent.getInstance().setMsgCount(unCheckedCount));

        MethodChannelFlutterPlugins.send("unReadUU", unCheckedUUCount);
        MethodChannelFlutterPlugins.send("unReadUCG", unCheckedUCGCount);
    }

    @Override
    public int getUnCheckedMsgCount(long uidInt) {
        return domainCommonManger.getUnCheckedMsgCount(uidInt);
    }


    @Override
    public int getTalkListMessageSize(long uid) {
        return chatMessageRepo.getTalkListMessageSize(uid);
    }

    @Override
    public void notifyMsgListViewUserReaded(ImSessionListAdapter mAdapter, long toUserId, int type) {
        List<ChatMessage> messages = mAdapter.getData();
        int size = messages.size();
        for (int i = 0; i < size; i++) {
            ChatMessage message = messages.get(i);
            if(type == ChatMessage.MSG_TYPE_UU && message.getMsgType() == ChatMessage.MSG_TYPE_UU){
                if(message.getType() == ChatMessage.TYPE_RECEIVE && message.getFromId() == toUserId
                        ){
                    message.setUnCheckedCount(0);
                    mAdapter.notifyItemChanged(i);
                    break;
                }else if(message.getType() == ChatMessage.TYPE_SEND && message.getToId() == toUserId){
                    message.setUnCheckedCount(0);
                    mAdapter.notifyItemChanged(i);
                    break;
                }
            }else if(type == ChatMessage.MSG_TYPE_UCG && message.getMsgType() == ChatMessage.MSG_TYPE_UCG){
                if(message.getChatGroupId() == toUserId){
                    message.setUnCheckedCount(0);
                    mAdapter.notifyItemChanged(i);
                    break;
                }
            }
        }
    }

    @Override
    public List<ChatMessage> getGroupTalkListMessage(int uidInt) {
        return chatMessageRepo.getGroupTalkListMessage(uidInt);
    }

    @Override
    public List<ChatMessage> getPersonalTalkListMessage(int uidInt) {
        return chatMessageRepo.getPersonalTalkListMessage(uidInt);
    }


    @Override
    public void notifyMsgListViewChange(ImSessionListAdapter mAdapter, ChatMessage newMsg) {
        List<ChatMessage> messages = mAdapter.getData();
        if (messages.size() == 0) {
            if(newMsg.getType() == ChatMessage.TYPE_RECEIVE) {
                newMsg.setUnCheckedCount(1);
            }else {
                newMsg.setUnCheckedCount(0);
            }
            messages.add(0, newMsg);
            mAdapter.notifyDataSetChanged();
            return;
        }
        ChatMessage firstTalk = messages.get(0);
        boolean isSameTalk = isSameTalk(newMsg, firstTalk);
        if (isSameTalk) {
            ChatMessage removeMsg = messages.remove(0);
            if(newMsg.getType() == ChatMessage.TYPE_RECEIVE) {
                newMsg.setUnCheckedCount(removeMsg.getUnCheckedCount() + 1);
            }else {
                newMsg.setUnCheckedCount(removeMsg.getUnCheckedCount());
            }
            messages.add(0, newMsg);
            mAdapter.notifyItemChanged(0);
        } else {

            int firstUnStick = 0;
            ChatMessage chatMessage;
            int size = messages.size();
            for (int i = 0; i < size; i++) {
                chatMessage = messages.get(i);
                if (!isMessageStick(chatMessage)) {
                    firstUnStick = i;
                    break;
                } else if(i == size - 1){
                    //如果全是置顶的
                    firstUnStick = size;
                }
            }
            //如果第一个非置顶位置是0或者全是置顶的，则没有必要进行以下判断
            if (firstUnStick != 0 && firstUnStick != size) {
                ChatMessage firstUnStickTalk = mAdapter.getItem(firstUnStick);
                isSameTalk = isSameTalk(newMsg, firstUnStickTalk);
                if (isSameTalk) {
                    ChatMessage removeMsg = messages.remove(firstUnStick);
                    if(newMsg.getType() == ChatMessage.TYPE_RECEIVE) {
                        newMsg.setUnCheckedCount(removeMsg.getUnCheckedCount() + 1);
                    }else {
                        newMsg.setUnCheckedCount(removeMsg.getUnCheckedCount());
                    }
                    messages.add(firstUnStick, newMsg);
                    mAdapter.notifyItemChanged(firstUnStick);
                    return;
                }
            }

            //如果不是第一条或非置顶第一条
            int newSize = getTalkListMessageSize(AccountHelper.getUidInt());
            //如果不同，说明是新增的会话,需要notifyiteminsert
            if (newSize != size) {
                if(newMsg.getType() == ChatMessage.TYPE_RECEIVE) {
                    newMsg.setUnCheckedCount(1);
                }else {
                    newMsg.setUnCheckedCount(0);
                }

                messages.add(firstUnStick, newMsg);
                mAdapter.notifyItemInserted(firstUnStick);
            } else {
                //如果相同，说明是需要移动位置的对话,需要notifyrangechange
                int needMoveIndex = 0;
                for (int i = 0; i < size; i++) {
                    if (isSameTalk(newMsg, messages.get(i))) {
                        needMoveIndex = i;
                        break;
                    }
                }
                ChatMessage oldMsg = messages.remove(needMoveIndex);
                if(newMsg.getType() == ChatMessage.TYPE_RECEIVE) {
                    newMsg.setUnCheckedCount(oldMsg.getUnCheckedCount() + 1);
                }else {
                    newMsg.setUnCheckedCount(oldMsg.getUnCheckedCount());
                }
                if (isMessageStick(oldMsg)) {
                    messages.add(0, newMsg);
                } else {
                    messages.add(firstUnStick, newMsg);
                }
                mAdapter.notifyItemRangeChanged(0, needMoveIndex + 1);
            }

        }
    }



    @Override
    public void updateChatMessageStatus(String uuid, int statusFailTimeout) {
        ChatMessage message = chatMessageRepo.getChatMessageByUUid(uuid, AccountHelper.getUidInt());
        if(message != null){
            message.setStatus(statusFailTimeout);
            chatMessageRepo.updateChatMessage(message);
        }
    }

    @Override
    public void updateMessageStatusToFail(long uidInt) {
        chatMessageRepo.updateMessageStatusToFail(uidInt);
    }

    @Override
    public boolean isMessageStick(ChatMessage item) {
        return chatMessageRepo.isStickMessage(item);
    }


    @Override
    public void getKlineContentBean(String name, String exchange, final String logo, final GetResultCallBack getResultCallBack) {
        HashMap<String, String> map = new HashMap<>();
        map.put("pair", name);
        map.put("exchange", exchange);
        OKHttpGetReq okHttpGetReq = new OKHttpGetReq(mContext, NetConstant.COINS_DETAIL);
        okHttpGetReq.getDataWithParam(new Callback() {
            @Override
            public void onError(String resp) {
                if(getResultCallBack != null){
                    getResultCallBack.fail(resp);
                }
            }

            @Override
            public void onResponse(String resp, int id) {
                try{
                    CoinsDetailPOJO detailPOJO = GsonUtil.buildGson().fromJson(resp, CoinsDetailPOJO.class);
                    CoinsDetailPOJO.TickerBeanX ticker = detailPOJO.getTicker();
                    KlineContentBean contentBean = new KlineContentBean();
                    contentBean.setImg(logo);
                    contentBean.setPrice(ticker.getTicker().getLast());
                    contentBean.setChange(FormatUtil.percentCSighed(ticker.getTicker().getLast(), ticker.getTicker().getPrice_24h_before()) + "%");
                    contentBean.setCoin(ticker.getCoin());
                    contentBean.setExchange(ticker.getExchange());
                    contentBean.setCurrency(ticker.getCurrency());
                    if(getResultCallBack != null){
                        getResultCallBack.success(contentBean.toJsonString());
                    }
                }catch (Exception e){
                    LogUtils.d("author" + "getKlineContentBean" + e.getMessage());
                }
            }
        }, map);
    }

    @Override
    public void updateChatMessageContent(String uuid, String downLoadFileName) {
        ChatMessage chatMessage = chatMessageRepo.getChatMessageByUUid(uuid, AccountHelper.getUidInt());
        if(chatMessage != null){
            chatMessage.setContent(downLoadFileName);
            boolean success = chatMessageRepo.updateChatMessage(chatMessage);
        }

    }

    /**
     * 重发失败消息的时候需要重新添加消息，改变uuid
     * @param uuid
     * @param uuid1
     */
    @Override
    public ChatMessage replaceChatMessageByUuid(String uuid, String uuid1) {
        ChatMessage chatMessageByUUid = chatMessageRepo.getChatMessageByUUid(uuid, AccountHelper.getUidInt());
        chatMessageRepo.deleteChatMessageByUuid(uuid, AccountHelper.getUidInt());
        if(chatMessageByUUid != null){
            chatMessageByUUid.setId(null);
            chatMessageByUUid.setUuid(uuid1);
            chatMessageRepo.addChatMessage(chatMessageByUUid, AccountHelper.getUidInt());
            return chatMessageByUUid;
        }
        return null;
    }

    @Override
    public long getMaxMessageIdByUserId(long userId) {
        return chatMessageRepo.getMaxMessageIdByUserId(userId);
    }

    @Override
    public boolean addChatMessage(ChatMessage message, long uidInt) {
        //在这里处理一下通知消息中的特殊模板
        return chatMessageRepo.addChatMessage(message, uidInt);
    }

    @Override
    public void updateChatMessage(ChatMessage message) {
        chatMessageRepo.updateChatMessage(message);
    }

    @Override
    public void updateCircleStick(long mCircleId, boolean b) {
        chatMessageRepo.updateCircleStick(mCircleId, b);
    }

    @Override
    public boolean getCircleStick(long mCircleId, int msgTypeUcg) {
        return chatMessageRepo.getCircleStick(mCircleId, msgTypeUcg);
    }

    @Override
    public void deleteChatMessageById(Long id) {
        chatMessageRepo.deleteChatMessageById(id);
    }

    @Override
    public List<ChatMessage> getChatMessageList(long uidInt, long toUserId, int chatType, int fetchSize, long ltMessageId, long gtMessageId) {
        return chatMessageRepo.getChatMessageList(uidInt, toUserId, chatType, fetchSize,  ltMessageId, gtMessageId);
    }

    @Override
    public long getUnReadCount(long uidInt, long toUserId, int chatType) {
        return chatMessageRepo.getUnReadCount(uidInt, toUserId, chatType);
    }

    @Override
    public void updateChatMessageStick(Long id, boolean b) {
        chatMessageRepo.updateChatMessageStick(id, b);
    }

    @Override
    public List<ChatMessage> getTalkListMessage(long uid) {
        return chatMessageRepo.getTalkListMessage(uid);
    }

    @Override
    public int getUncheckedMessageCountExceptNoDisturb(long uidInt, List<Long> noDisturbGroupIds) {
        return chatMessageRepo.getUncheckedMessageCountExceptNoDisturb(uidInt, noDisturbGroupIds);
    }

    @Override
    public void deleteCircleChatMessage(long uidInt, long mCircleId) {
        chatMessageRepo.deleteListChatMessage(uidInt, mCircleId, ChatMessage.MSG_TYPE_UCG);
    }


    @Override
    public List<ChatMessage> getLocChatMessageList(long uidInt, long toUserId, int chatType, int pageSize, long locMessageId) {
        return chatMessageRepo.getLocChatMessageList(uidInt, toUserId, chatType, pageSize, locMessageId);
    }

    @Override
    public ChatMessage getChatMessageListByUUid(String uuid) {
        return chatMessageRepo.getChatMessageByUUid(uuid, AccountHelper.getUidInt());
    }



    @Override
    public List<ChatMessage> searchChatMessagePaged(String word, int pageSize, int page, String orderField, String orderType) {
        return chatMessageRepo.searchChatMessagePaged(word, pageSize, page, orderField, orderType);
    }


//    private boolean isSameTalk(ChatMessage onLineMessage, ChatMessage item) {
//        boolean isSameTalk = false;
//        if (onLineMessage.getMsgType() != item.getMsgType()) {
//            return false;
//        }
//
//        if (item.getMsgType() == ChatMessage.MSG_TYPE_UU) {
//            if (item.getType() == ChatMessage.TYPE_SEND) {
//                if (item.getToId() == onLineMessage.getFromId()) {
//                    isSameTalk = true;
//                }
//            } else if (item.getType() == ChatMessage.TYPE_RECEIVE) {
//                if (item.getFromId() == onLineMessage.getFromId()) {
//                    isSameTalk = true;
//                }
//            }
//        } else if (item.getMsgType() == ChatMessage.MSG_TYPE_UCG) {
//            if (item.getChatGroupId() == onLineMessage.getChatGroupId()) {
//                isSameTalk = true;
//            }
//        }
//        return isSameTalk;
//    }

    private boolean isSameTalk(ChatMessage aMessage, ChatMessage bMessage) {
        if(aMessage.getMsgType() != bMessage.getMsgType()){
            return false;
        }
        if(aMessage.getMsgType() == ChatMessage.MSG_TYPE_UCG){
            return aMessage.getChatGroupId() == bMessage.getChatGroupId();
        }
        if (aMessage.getType() == ChatMessage.TYPE_RECEIVE && bMessage.getType() == ChatMessage.TYPE_RECEIVE) {
            return  aMessage.getFromId() == bMessage.getFromId();
        } else if(aMessage.getType() == ChatMessage.TYPE_SEND && bMessage.getType() == ChatMessage.TYPE_SEND){
            return aMessage.getToId() == bMessage.getToId();
        } else if(aMessage.getType() == ChatMessage.TYPE_SEND && bMessage.getType() == ChatMessage.TYPE_RECEIVE){
            return aMessage.getToId() == bMessage.getFromId();
        } else {
            return aMessage.getFromId() == bMessage.getToId();
        }
    }

}
